{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i am user\n",
      "i am baseclass\n"
     ]
    }
   ],
   "source": [
    "## 类也是对象，type创建类的类\n",
    "## 如何动态创建类\n",
    "\n",
    "def create_class(name):\n",
    "    if name == \"user\":\n",
    "        class User:\n",
    "            def __str__(self):\n",
    "                return \"user\"\n",
    "        return User\n",
    "    elif name == \"company\":\n",
    "        class Company:\n",
    "            def __str__(self):\n",
    "                return \"company\"\n",
    "        return Company\n",
    "\n",
    "## type 动态创建类\n",
    "## 如果存在基类，则基类后的逗号不能省略\n",
    "## type(\"名称\", (基类, ), {属性})\n",
    "# User = type(\"User\", (), {\"name\": \"user\"})\n",
    "\n",
    "## 绑定在User类上的方法\n",
    "def say(self):\n",
    "    return \"i am user\"\n",
    "\n",
    "\n",
    "class BaseClass:\n",
    "    def answer(self):\n",
    "        return \"i am baseclass\"\n",
    "\n",
    "################################\n",
    "## 什么是元类：是创建类的类\n",
    "## type就是元类\n",
    "## 对象 <- class（对象）<- type\n",
    "################################\n",
    "## python 中类的实例化过程，首先去寻找metaclass，如果找到了，会调用metaclass实例化（创建）User类\n",
    "## 如果User有metaclass则使用User的，如果没有，则调用基类的metaclass，再没有则去模块找\n",
    "# class Metaclass(type):\n",
    "#     pass\n",
    "# class BaseClass(metaclass=MetaClass):\n",
    "#     pass\n",
    "# class User(Baseclass, metaclass=xxxx):\n",
    "#     pass\n",
    "    \n",
    "if __name__ == \"__main__\":\n",
    "    ## 方法1:\n",
    "#     MyClass = create_class(\"user\")\n",
    "#     my_obj = MyClass()\n",
    "#     print(my_obj)\n",
    "    \n",
    "    ## 方法2:\n",
    "    User = type(\"User\", (BaseClass,), {\"name\": \"user\", \"say\": say})\n",
    "    my_obj = User()\n",
    "    print(my_obj.say())\n",
    "    print(my_obj.answer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "user\n"
     ]
    }
   ],
   "source": [
    "# class BaseClass:\n",
    "#     def answer(self):\n",
    "#         return \"i am baseclass\"\n",
    "\n",
    "class MetaClass(type):\n",
    "    def __new__(cls, *args, **kwargs):\n",
    "        return super().__new__(cls, *args, **kwargs)\n",
    "    \n",
    "class User(metaclass=MetaClass):\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "    def __str__(self):\n",
    "        return \"user\"\n",
    "    \n",
    "if __name__ == \"__main__\":\n",
    "    my_obj = User(name=\"bobby\")\n",
    "    print(my_obj)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
